﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;

namespace ZZT
{
    public class ZZTBoard : Board
    {
        Heap heap;
        byte[] memory;
        Pointer pointer;

        Pointer dark;
        Pointer enter;
        Pointer exits;
        Pointer maxshots;
        Pointer name;
        Pointer restart;
        Pointer timelimit;

        public ZZTBoard(byte[] memory, Heap heap)
        {
            this.heap = heap;
            this.memory = memory;
            this.pointer = new Pointer(memory, 0);

            name = new Pointer(memory, 0x2486);
            maxshots = new Pointer(memory, 0x4567);
            dark = new Pointer(memory, 0x4568);
            exits = new Pointer(memory, 0x4569);
            restart = new Pointer(memory, 0x456D);
            enter = new Pointer(memory, 0x45A9);
            timelimit = new Pointer(memory, 0x45AB);
        }

        public override Tile this[int index]
        {
            get { return new Tile(memory, 0x24B9 + (index * 2)); }
        }

        public override Tile this[Point point]
        {
            get { return new Tile(memory, 0x24B9 + (((point.X * HeightTotal) + point.Y) * 2)); }
        }

        public override bool Dark
        {
            get
            {
                return dark.Bool;
            }
            set
            {
                dark.Bool = value;
            }
        }

        public override Tile EdgeTile
        {
            get { return new Tile(memory, 0x0074); }
        }

        public override int ExitEast
        {
            get
            {
                return exits[3];
            }
            set
            {
                exits[3] = (byte)(value & 0xFF);
            }
        }

        public override int ExitNorth
        {
            get
            {
                return exits[0];
            }
            set
            {
                exits[0] = (byte)(value & 0xFF);
            }
        }

        public override int ExitSouth
        {
            get
            {
                return exits[1];
            }
            set
            {
                exits[1] = (byte)(value & 0xFF);
            }
        }

        public override int ExitWest
        {
            get
            {
                return exits[2];
            }
            set
            {
                exits[2] = (byte)(value & 0xFF);
            }
        }

        public override int Height
        {
            get { return 25; }
        }

        public override int MaximumShots
        {
            get
            {
                return maxshots.Int8;
            }
            set
            {
                maxshots.Int8 = value;
            }
        }

        public override string Name
        {
            get
            {
                return name.String;
            }
            set
            {
                name.String = value;
            }
        }

        public override int NameLength
        {
            get { return 50; }
        }

        public override void Pack(Stream target)
        {
            using (MemoryStream mem = new MemoryStream())
            {
                BinaryWriter writer = new BinaryWriter(mem);

                writer.Write(memory, 0x2486, NameLength + 1);
                CompressRLE(mem);
                writer.Write(memory, 0x4567, 86);
            }
        }

        public override int PlayerEnterX
        {
            get
            {
                return enter[0];
            }
            set
            {
                enter[0] = (byte)(value & 0xFF);
            }
        }

        public override int PlayerEnterY
        {
            get
            {
                return enter[1];
            }
            set
            {
                enter[1] = (byte)(value & 0xFF);
            }
        }

        public override bool RestartOnZap
        {
            get
            {
                return restart.Bool;
            }
            set
            {
                restart.Bool = value;
            }
        }

        public override int TimeLimit
        {
            get
            {
                return timelimit.Int16;
            }
            set
            {
                timelimit.Int16 = value;
            }
        }

        public override void UnPack(Stream source)
        {
            throw new NotImplementedException();
        }

        public override int Width
        {
            get { return 60; }
        }
    }
}
